from wxpyview.ui.component.common.basewidget import *
from wxpyview.ui.component.widgets.sizer.flexgrid.FlexGridCell import *

class FlexGridSizer(Widget):
    def _getParentParam(self, meta_widget):
        stopping_point = ['BoxSizer', 'FlexGridSizer', 'Panel', 'Frame']       
        return ComponentLibrary.findFirstMatchedAncestor(meta_widget, stopping_point)
    
    def _setParams(self, meta_widget):
        dom = meta_widget.getDOM()
        if not dom:
            raise IOException
        
        self.params["rows"] = FlexGridSizer._getNumOfFlexGridRows(meta_widget)  
        self.params["cols"] = FlexGridSizer._getNumOfFlexGridCols(meta_widget)
        self.params["hgap"] = ComponentLibrary.str2int(dom.getAttribute("hgap"), 0)
        self.params["vgap"] = ComponentLibrary.str2int(dom.getAttribute("vgap"), 0)

        self.growableCol = ComponentLibrary.str2int(dom.getAttribute("glowableCol"), None)

    def create(self, meta_widget):
        self._setParams(meta_widget)

        sizer = wx.FlexGridSizer(**self.params)
        
        if self.growableCol != None:
            sizer.AddGrowableCol(self.growableCol)

        parent = self._getParentParam(meta_widget)

        parent_classname = parent.__class__.__name__
        
        if parent_classname not in ['BoxSizer', 'FlexGridSizer']:
            parent.SetSizer(sizer)

        return sizer
        
    @classmethod
    def finalize(cls, meta_widget):
        current_widget = meta_widget.getWidget()

        flexGridRow_meta_widgets = meta_widget.getChildMetaWidgets()
        
        for row_meta_widget in flexGridRow_meta_widgets:
            flexGridCell_meta_widgets = row_meta_widget.getChildMetaWidgets()
            for cell_meta_widget in flexGridCell_meta_widgets:
                widget = FlexGridCell.getWidget(cell_meta_widget)

                if widget == None: continue
                
                sizer_params = cell_meta_widget.getWidget().getSizerParams()
                
                current_widget.Add(widget, **sizer_params)

    @classmethod
    def _getNumOfFlexGridRows(cls, meta_widget):
        flexGridRow_meta_widgets = meta_widget.getChildMetaWidgets()
        
        # check if tag "wx:FlexGrid" has children which are not "wx:FlexGridRow"
        nodes_validity = map(lambda x: x.getDOM().nodeName == "wx:FlexGridRow", flexGridRow_meta_widgets)
        if len(filter(None, nodes_validity)) != len(flexGridRow_meta_widgets):
            # wx:FlexGrid contains invalid children (other than wx:FlexGridRow)
            raise IOException
        
        return len(flexGridRow_meta_widgets)
    
    @classmethod
    def _getNumOfFlexGridCols(cls, meta_widget):
        flexGridRow_meta_widgets = meta_widget.getChildMetaWidgets()
        
        numOfCellsInRows = None

        for flexGridRow_meta_widget in flexGridRow_meta_widgets:
            flexGridCell_meta_widgets = flexGridRow_meta_widget.getChildMetaWidgets()
        
            # check if tag "wx:FlexGridRow" has children which are not "wx:FlexGridCell"
            nodes_validity = map(lambda x: x.getDOM().nodeName == "wx:FlexGridCell", flexGridCell_meta_widgets)
            if len(filter(None, nodes_validity)) != len(flexGridCell_meta_widgets):
                # wx:FlexGridRow contains invalid children (other than wx:FlexGridCell)
                raise IOException
        
            if numOfCellsInRows == None: numOfCellsInRows = len(flexGridCell_meta_widgets)
            elif numOfCellsInRows != len(flexGridCell_meta_widgets):
                # number of cells in each row doesn't match
                raise IOException
        
        return numOfCellsInRows